{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0",
   "metadata": {},
   "source": [
    "[![image](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/gee-community/geemap/blob/master/docs/workshops/CVPR_2025.ipynb)\n",
    "\n",
    "**An Introduction to Cloud-Based Geospatial Analysis with Earth Engine and Geemap**\n",
    "\n",
    "-   Notebook: <https://geemap.org/workshops/CVPR_2025>\n",
    "-   Earth Engine: <https://earthengine.google.com>\n",
    "-   Geemap: <https://geemap.org>\n",
    "\n",
    "## Introduction\n",
    "\n",
    "This notebook is for the workshop (Computer Vision and Artificial Intelligence for Large-Scale Earth Observation Data) presented at the [IEEE / CVF Computer Vision and Pattern Recognition Conference (CVPR) ](https://cvpr.thecvf.com).\n",
    "\n",
    "Participants will dive into Google Earth Engine and Geemap to create interactive maps and analyze large-scale geospatial datasets. Topics include:\n",
    "\n",
    "* Building interactive maps\n",
    "* Visualizing and analyzing Earth Engine datasets\n",
    "* Exploring Earth Engine Data Catalogs\n",
    "* Exporting data for further use\n",
    "* Creating timelapse animations\n",
    "\n",
    "## Prerequisites\n",
    "\n",
    "-   To use geemap and the Earth Engine Python API, you must [register](https://code.earthengine.google.com/register) for an Earth Engine account and follow the instructions [here](https://docs.google.com/document/d/1ZGSmrNm6_baqd8CHt33kIBWOlvkh-HLr46bODgJN1h0/edit?usp=sharing) to create a Cloud Project. Earth Engine is free for [noncommercial and research use](https://earthengine.google.com/noncommercial). To test whether you can use authenticate the Earth Engine Python API, please run [this notebook](https://colab.research.google.com/github/gee-community/geemap/blob/master/docs/notebooks/00_geemap_colab.ipynb) on Google Colab.\n",
    "\n",
    "-   It is recommended that attendees have a basic understanding of Python and Jupyter Notebook.\n",
    "-   Familiarity with the Earth Engine JavaScript API is not required but will be helpful.\n",
    "-   Attendees can use Google Colab to follow this workshop without installing anything on their computer.\n",
    "\n",
    "## Introduction to Google Earth Engine\n",
    "\n",
    "### Google Earth Engine Overview\n",
    "\n",
    "[Google Earth Engine](https://earthengine.google.com) is a cloud-computing platform that enables scientific analysis and visualization of large-scale geospatial datasets. It provides a rich data catalog and processing capabilities, allowing users to analyze satellite imagery and geospatial data at planetary scale.\n",
    "\n",
    "Earth Engine is free for [noncommercial and research use](https://earthengine.google.com/noncommercial). Nonprofit organizations, research institutions, educators, Indigenous governments, and government researchers can continue using Earth Engine for free, as they have for more than a decade. However, [commercial users](https://earthengine.google.com/commercial) may require a paid license.\n",
    "\n",
    "### Installing Geemap\n",
    "\n",
    "The geemap package simplifies the use of Google Earth Engine in Python, offering an intuitive API for visualization and analysis in Jupyter notebooks. In Google Colab, geemap is pre-installed, but you may need to install additional dependencies for certain features. To install the latest version with optional dependencies, use the following command:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1",
   "metadata": {},
   "outputs": [],
   "source": [
    "# %pip install -U \"geemap[workshop]\" leafmap"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2",
   "metadata": {},
   "source": [
    "### Import Libraries\n",
    "\n",
    "To start, import the necessary libraries for working with Google Earth Engine (GEE) and geemap."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3",
   "metadata": {},
   "outputs": [],
   "source": [
    "import ee\n",
    "import geemap"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4",
   "metadata": {},
   "source": [
    "### Authenticate and Initialize Earth Engine\n",
    "\n",
    "To authenticate and initialize your Earth Engine environment, you’ll need to create a Google Cloud Project and enable the [Earth Engine API](https://console.cloud.google.com/apis/api/earthengine.googleapis.com) for the project if you have not done so already. You can find detailed setup instructions [here](https://developers.google.com/earth-engine/guides/access#a-role-in-a-cloud-project)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5",
   "metadata": {},
   "outputs": [],
   "source": [
    "ee.Authenticate()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6",
   "metadata": {},
   "source": [
    "Replace `YOUR-PROJECT-ID` with your actual Google Cloud Project ID. You can get the project ID from the [Earth Engine JavaScript Code Editor](https://code.earthengine.google.com/)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7",
   "metadata": {},
   "outputs": [],
   "source": [
    "ee.Initialize(project=\"Your_Project_ID\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8",
   "metadata": {},
   "source": [
    "### Creating Interactive Maps\n",
    "\n",
    "Let’s create an interactive map using the `ipyleaflet` plotting backend. The `geemap.Map` class inherits from the `ipyleaflet.Map` class, so the syntax is similar to creating an interactive map with `ipyleaflet.Map`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "10",
   "metadata": {},
   "source": [
    "To display the map in a Jupyter notebook, simply enter the map object:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "11",
   "metadata": {},
   "outputs": [],
   "source": [
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "12",
   "metadata": {},
   "source": [
    "To customize the map’s display, you can set various keyword arguments, such as `center` (latitude and longitude), `zoom`, `width`, and `height`. By default, the `width` is `100%`, filling the entire width of the Jupyter notebook cell. The `height` parameter can be a number (in pixels) or a string with a pixel format, e.g., `600px`.\n",
    "\n",
    "**Map of the Contiguous United States**\n",
    "\n",
    "  To center the map on the contiguous United States, use:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "13",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map(center=[40, -100], zoom=4, height=\"600px\")\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "14",
   "metadata": {},
   "source": [
    "**Map of the state of Tennessee**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "15",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map(center=[35.746512, -86.209818], zoom=8)\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "16",
   "metadata": {},
   "source": [
    "### Adding Basemaps\n",
    "\n",
    "There are several ways to add basemaps to a map in geemap. You can specify a basemap in the `basemap` keyword argument when creating the map, or you can add additional basemap layers using the `add_basemap` method. `Geemap` provides access to hundreds of built-in basemaps, making it easy to add layers to a map with a single line of code.\n",
    "\n",
    "To create a map with a specific basemap, use the `basemap` argument as shown below. For example, `Esri.WorldImagery` provides an Esri world imagery basemap."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "17",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map(basemap=\"Esri.WorldImagery\")\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "18",
   "metadata": {},
   "source": [
    "## Introduction to Interactive Maps and Tools\n",
    "\n",
    "### Basemap Selector\n",
    "\n",
    "The basemap selector allows you to choose from various basemaps via a dropdown menu. Adding it to your map provides easy access to different map backgrounds."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "19",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map()\n",
    "m.add(\"basemap_selector\")\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "20",
   "metadata": {},
   "source": [
    "### Layer Manager\n",
    "\n",
    "The layer manager provides control over layer visibility and transparency. It enables toggling layers on and off and adjusting transparency with a slider, making it easy to customize map visuals."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "21",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map(center=(40, -100), zoom=4)\n",
    "dem = ee.Image(\"USGS/SRTMGL1_003\")\n",
    "states = ee.FeatureCollection(\"TIGER/2018/States\")\n",
    "vis_params = {\n",
    "    \"min\": 0,\n",
    "    \"max\": 4000,\n",
    "    \"palette\": [\"006633\", \"E5FFCC\", \"662A00\", \"D8D8D8\", \"F5F5F5\"],\n",
    "}\n",
    "m.add_layer(dem, vis_params, \"SRTM DEM\")\n",
    "m.add_layer(states, {}, \"US States\")\n",
    "m.add(\"layer_manager\")\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "22",
   "metadata": {},
   "source": [
    "### Inspector Tool\n",
    "\n",
    "The inspector tool allows you to click on the map to query Earth Engine data at specific locations. This is helpful for examining the properties of datasets directly on the map."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "23",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map(center=(40, -100), zoom=4)\n",
    "dem = ee.Image(\"USGS/SRTMGL1_003\")\n",
    "landsat7 = ee.Image(\"LANDSAT/LE7_TOA_5YEAR/1999_2003\")\n",
    "states = ee.FeatureCollection(\"TIGER/2018/States\")\n",
    "vis_params = {\n",
    "    \"min\": 0,\n",
    "    \"max\": 4000,\n",
    "    \"palette\": [\"006633\", \"E5FFCC\", \"662A00\", \"D8D8D8\", \"F5F5F5\"],\n",
    "}\n",
    "m.add_layer(dem, vis_params, \"SRTM DEM\")\n",
    "m.add_layer(\n",
    "    landsat7,\n",
    "    {\"bands\": [\"B4\", \"B3\", \"B2\"], \"min\": 20, \"max\": 200, \"gamma\": 2.0},\n",
    "    \"Landsat 7\",\n",
    ")\n",
    "m.add_layer(states, {}, \"US States\")\n",
    "m.add(\"inspector\")\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "24",
   "metadata": {},
   "source": [
    "### Layer Editor\n",
    "\n",
    "With the layer editor, you can adjust visualization parameters of Earth Engine data for better clarity and focus. It supports single-band images, multi-band images, and feature collections.\n",
    "\n",
    "#### Single-Band image"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "25",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map(center=(40, -100), zoom=4)\n",
    "dem = ee.Image(\"USGS/SRTMGL1_003\")\n",
    "vis_params = {\n",
    "    \"min\": 0,\n",
    "    \"max\": 4000,\n",
    "    \"palette\": [\"006633\", \"E5FFCC\", \"662A00\", \"D8D8D8\", \"F5F5F5\"],\n",
    "}\n",
    "m.add_layer(dem, vis_params, \"SRTM DEM\")\n",
    "m.add(\"layer_editor\", layer_dict=m.ee_layers[\"SRTM DEM\"])\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "26",
   "metadata": {},
   "source": [
    "#### Multi-Band image"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "27",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map(center=(40, -100), zoom=4)\n",
    "landsat7 = ee.Image(\"LANDSAT/LE7_TOA_5YEAR/1999_2003\")\n",
    "m.add_layer(\n",
    "    landsat7,\n",
    "    {\"bands\": [\"B4\", \"B3\", \"B2\"], \"min\": 20, \"max\": 200, \"gamma\": 2.0},\n",
    "    \"Landsat 7\",\n",
    ")\n",
    "m.add(\"layer_editor\", layer_dict=m.ee_layers[\"Landsat 7\"])\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "28",
   "metadata": {},
   "source": [
    "#### Feature Collection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "29",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map(center=(40, -100), zoom=4)\n",
    "states = ee.FeatureCollection(\"TIGER/2018/States\")\n",
    "m.add_layer(states, {}, \"US States\")\n",
    "m.add(\"layer_editor\", layer_dict=m.ee_layers[\"US States\"])\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "30",
   "metadata": {},
   "source": [
    "### Draw Control\n",
    "\n",
    "The draw control feature allows you to draw shapes directly on the map, converting them automatically into Earth Engine objects. Access the drawn features as follows:\n",
    "\n",
    "- To return the last drawn feature as an `ee.Geometry()`, use `m.user_roi`\n",
    "- To return all drawn features as an `ee.FeatureCollection()`, use `m.user_rois`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "31",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map(center=(40, -100), zoom=4)\n",
    "dem = ee.Image(\"USGS/SRTMGL1_003\")\n",
    "vis_params = {\n",
    "    \"min\": 0,\n",
    "    \"max\": 4000,\n",
    "    \"palette\": \"terrain\",\n",
    "}\n",
    "m.add_layer(dem, vis_params, \"SRTM DEM\")\n",
    "m.add(\"layer_manager\")\n",
    "m"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "32",
   "metadata": {},
   "outputs": [],
   "source": [
    "if m.user_roi is not None:\n",
    "    image = dem.clip(m.user_roi)\n",
    "    m.layers[1].visible = False\n",
    "    m.add_layer(image, vis_params, \"Clipped DEM\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "33",
   "metadata": {},
   "source": [
    "## The Earth Engine Data Catalog\n",
    "\n",
    "The [Earth Engine Data Catalog](https://developers.google.com/earth-engine/datasets) hosts an extensive collection of geospatial datasets. Currently, he catalog includes over [1,000 datasets](https://github.com/opengeos/Earth-Engine-Catalog/blob/master/gee_catalog.tsv) with a combined size exceeding 100 petabytes. Notable datasets include Landsat, Sentinel, MODIS, and NAIP. For a comprehensive list of datasets in CSV or JSON format, refer to the [Earth Engine Datasets List](https://github.com/giswqs/Earth-Engine-Catalog/blob/master/gee_catalog.tsv).\n",
    "\n",
    "### Searching Datasets on the Earth Engine Website\n",
    "\n",
    "To browse datasets directly on the Earth Engine website:\n",
    "\n",
    "- View the full catalog: https://developers.google.com/earth-engine/datasets/catalog\n",
    "- Search by tags: https://developers.google.com/earth-engine/datasets/tags\n",
    "\n",
    "### Searching Datasets Within Geemap\n",
    "\n",
    "The [Earth Engine Data Catalog](https://developers.google.com/earth-engine/datasets/catalog) can also be searched directly from `geemap`. Use keywords to filter datasets by name, tag, or description. For instance, searching for \"elevation\" will display only datasets containing \"elevation\" in their metadata, returning 52 datasets. You can scroll through the results to locate the [NASA SRTM Digital Elevation 30m](https://developers.google.com/earth-engine/datasets/catalog/USGS_SRTMGL1_003#description) dataset."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "34",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map()\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "35",
   "metadata": {},
   "source": [
    "![](https://i.imgur.com/B3rf4QN.jpg)\n",
    "\n",
    "Each dataset page contains detailed information such as availability, provider, Earth Engine snippet, tags, description, and example code. The Image, ImageCollection, or FeatureCollection ID is essential for accessing the dataset in Earth Engine’s JavaScript or Python APIs."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "36",
   "metadata": {},
   "source": [
    "## Earth Engine Data Types\n",
    "\n",
    "Earth Engine objects are server-side entities, meaning they are stored and processed on Earth Engine’s servers rather than locally. This setup is comparable to streaming services (e.g., YouTube or Netflix) where the data remains on the provider’s servers, allowing us to access and process geospatial data in real time without downloading it to our local devices.\n",
    "\n",
    "- **Image**: The core raster data type in Earth Engine, representing single images or scenes.\n",
    "- **ImageCollection**: A collection or sequence of images, often used for time series analysis.\n",
    "- **Geometry**: The fundamental vector data type, including shapes like points, lines, and polygons.\n",
    "- **Feature**: A Geometry with associated attributes, used to add descriptive data to vector shapes.\n",
    "- **FeatureCollection**: A collection of Features, similar to a shapefile with attribute data.\n",
    "\n",
    "## Earth Engine Raster Data\n",
    "\n",
    "### Image\n",
    "\n",
    "In Earth Engine, raster data is represented as **Image** objects. Each Image is composed of bands, with each band having its own name, data type, scale, mask, and projection. Metadata for each image is stored as a set of properties.\n",
    "\n",
    "#### Loading Earth Engine Images\n",
    "\n",
    "To load images, use the Earth Engine asset ID within the `ee.Image` constructor. Asset IDs can be found in the Earth Engine Data Catalog. For example, to load the NASA SRTM Digital Elevation dataset:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "37",
   "metadata": {},
   "outputs": [],
   "source": [
    "image = ee.Image(\"USGS/SRTMGL1_003\")\n",
    "image"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "38",
   "metadata": {},
   "source": [
    "#### Visualizing Earth Engine Images\n",
    "\n",
    "To visualize an image, you can specify visualization parameters such as minimum and maximum values and color palettes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "39",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map(center=[21.79, 70.87], zoom=3)\n",
    "image = ee.Image(\"USGS/SRTMGL1_003\")\n",
    "vis_params = {\n",
    "    \"min\": 0,\n",
    "    \"max\": 6000,\n",
    "    \"palette\": [\"006633\", \"E5FFCC\", \"662A00\", \"D8D8D8\", \"F5F5F5\"],  # 'terrain'\n",
    "}\n",
    "m.add_layer(image, vis_params, \"SRTM\")\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "40",
   "metadata": {},
   "source": [
    "### ImageCollection\n",
    "\n",
    "An **ImageCollection** represents a sequence of images, often used for temporal data like satellite image time series. ImageCollections are created by passing an Earth Engine asset ID into the `ImageCollection` constructor. Asset IDs are available in the [Earth Engine Data Catalog](https://developers.google.com/earth-engine/datasets).\n",
    "\n",
    "#### Loading Image Collections\n",
    "\n",
    "To load an ImageCollection, such as the Sentinel-2 surface reflectance collection:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "41",
   "metadata": {},
   "outputs": [],
   "source": [
    "collection = ee.ImageCollection(\"COPERNICUS/S2_SR_HARMONIZED\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "42",
   "metadata": {},
   "source": [
    "#### Filtering Image Collections\n",
    "\n",
    "You can filter ImageCollections by location and time. For example, to filter images covering a specific location with low cloud cover:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "43",
   "metadata": {},
   "outputs": [],
   "source": [
    "geometry = ee.Geometry.Point([-86.781999, 36.155265])\n",
    "images = collection.filterBounds(geometry)\n",
    "images.size()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "44",
   "metadata": {},
   "outputs": [],
   "source": [
    "images.first()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "45",
   "metadata": {},
   "outputs": [],
   "source": [
    "images = (\n",
    "    collection.filterBounds(geometry)\n",
    "    .filterDate(\"2025-03-01\", \"2025-06-10\")\n",
    "    .filter(ee.Filter.lt(\"CLOUDY_PIXEL_PERCENTAGE\", 5))\n",
    ")\n",
    "images.size()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "46",
   "metadata": {},
   "source": [
    "To view the filtered collection on a map:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "47",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map()\n",
    "image = images.first()\n",
    "\n",
    "vis = {\n",
    "    \"min\": 0.0,\n",
    "    \"max\": 3000,\n",
    "    \"bands\": [\"B4\", \"B3\", \"B2\"],\n",
    "}\n",
    "\n",
    "m.add_layer(image, vis, \"Sentinel-2\")\n",
    "m.centerObject(image, 8)\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "48",
   "metadata": {},
   "source": [
    "#### Visualizing Image Collections\n",
    "\n",
    "To visualize an **ImageCollection** as a single composite image, you need to aggregate the collection. For example, using the `collection.median()` method creates an image representing the median value across the collection."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "49",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map()\n",
    "image = images.median()\n",
    "\n",
    "vis = {\n",
    "    \"min\": 0.0,\n",
    "    \"max\": 3000,\n",
    "    \"bands\": [\"B8\", \"B4\", \"B3\"],\n",
    "}\n",
    "\n",
    "m.add_layer(image, vis, \"Sentinel-2\")\n",
    "m.centerObject(geometry, 8)\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "50",
   "metadata": {},
   "source": [
    "## Earth Engine Vector Data\n",
    "\n",
    "A **FeatureCollection** is a collection of Features. It functions similarly to a GeoJSON FeatureCollection, where features include associated properties or attributes. For example, a shapefile’s data can be represented as a FeatureCollection.\n",
    "\n",
    "### Loading Feature Collections\n",
    "\n",
    "The [Earth Engine Data Catalog](https://developers.google.com/earth-engine/datasets) includes various vector datasets, such as U.S. Census data and country boundaries, as feature collections. Feature Collection IDs are accessible by searching the data catalog. For example, to load the [TIGER roads data](https://developers.google.com/earth-engine/datasets/catalog/TIGER_2016_Roads) by the U.S. Census Bureau:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "51",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map()\n",
    "fc = ee.FeatureCollection(\"TIGER/2016/Roads\")\n",
    "m.set_center(-83.909463, 35.959111, 12)\n",
    "m.add_layer(fc, {}, \"Census roads\")\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "52",
   "metadata": {},
   "source": [
    "### Filtering Feature Collections\n",
    "\n",
    "The `filter` method allows you to filter a FeatureCollection based on certain attribute values. For instance, we can filter for specific states using the `eq` filter to select \"Tennessee\":"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "53",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map()\n",
    "states = ee.FeatureCollection(\"TIGER/2018/States\")\n",
    "fc = states.filter(ee.Filter.eq(\"NAME\", \"Tennessee\"))\n",
    "m.add_layer(fc, {}, \"Tennessee\")\n",
    "m.center_object(fc, 7)\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "54",
   "metadata": {},
   "source": [
    "To retrieve properties of the first feature in the collection, use:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "55",
   "metadata": {},
   "outputs": [],
   "source": [
    "feat = fc.first()\n",
    "feat.toDictionary()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "56",
   "metadata": {},
   "source": [
    "You can also convert a FeatureCollection to a Pandas DataFrame for easier analysis with:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "57",
   "metadata": {},
   "outputs": [],
   "source": [
    "geemap.ee_to_df(fc)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "58",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map()\n",
    "states = ee.FeatureCollection(\"TIGER/2018/States\")\n",
    "fc = states.filter(ee.Filter.inList(\"NAME\", [\"California\", \"Oregon\", \"Washington\"]))\n",
    "m.add_layer(fc, {}, \"West Coast\")\n",
    "m.center_object(fc, 5)\n",
    "m"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "59",
   "metadata": {},
   "outputs": [],
   "source": [
    "region = m.user_roi\n",
    "if region is None:\n",
    "    region = ee.Geometry.BBox(-88.40, 29.88, -77.90, 35.39)\n",
    "\n",
    "fc = ee.FeatureCollection(\"TIGER/2018/States\").filterBounds(region)\n",
    "m.add_layer(fc, {}, \"Southeastern U.S.\")\n",
    "m.center_object(fc, 6)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "60",
   "metadata": {},
   "source": [
    "A FeatureCollection can be used to clip an image. The `clipToCollection` method clips an image to the geometry of a feature collection. For example, to clip a Landsat image to the boundary of France:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "61",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map(center=(40, -100), zoom=4)\n",
    "landsat7 = ee.Image(\"LANDSAT/LE7_TOA_5YEAR/1999_2003\")\n",
    "countries = ee.FeatureCollection(\"FAO/GAUL_SIMPLIFIED_500m/2015/level0\")\n",
    "fc = countries.filter(ee.Filter.eq(\"ADM0_NAME\", \"Germany\"))\n",
    "image = landsat7.clipToCollection(fc)\n",
    "m.add_layer(\n",
    "    image,\n",
    "    {\"bands\": [\"B4\", \"B3\", \"B2\"], \"min\": 20, \"max\": 200, \"gamma\": 2.0},\n",
    "    \"Landsat 7\",\n",
    ")\n",
    "m.center_object(fc, 6)\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "62",
   "metadata": {},
   "source": [
    "### Visualizing Feature Collections\n",
    "\n",
    "Once loaded, feature collections can be visualized on an interactive map. For example, visualizing U.S. state boundaries from the census data:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "63",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map(center=[40, -100], zoom=4)\n",
    "states = ee.FeatureCollection(\"TIGER/2018/States\")\n",
    "m.add_layer(states, {}, \"US States\")\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "64",
   "metadata": {},
   "source": [
    "Feature collections can also be styled with additional parameters. To apply a custom style, specify options like color and line width:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "65",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map(center=[40, -100], zoom=4)\n",
    "states = ee.FeatureCollection(\"TIGER/2018/States\")\n",
    "style = {\"color\": \"0000ffff\", \"width\": 2, \"lineType\": \"solid\", \"fillColor\": \"FF000080\"}\n",
    "m.add_layer(states.style(**style), {}, \"US States\")\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "66",
   "metadata": {},
   "source": [
    "## Exporting Earth Engine Data\n",
    "\n",
    "### Exporting Images\n",
    "\n",
    "This section demonstrates exporting Earth Engine images. First, a Landsat image is added to the map for visualization, and a rectangular region of interest (ROI) is specified. Exporting options include saving the image locally with specified scale and region or exporting to Google Drive. It’s possible to define custom CRS and transformation settings when saving the image.\n",
    "\n",
    "\n",
    "Add a Landsat image to the map."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "67",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map()\n",
    "\n",
    "image = ee.Image(\"LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140318\").select(\n",
    "    [\"B5\", \"B4\", \"B3\"]\n",
    ")\n",
    "\n",
    "vis_params = {\"min\": 0, \"max\": 0.5, \"gamma\": [0.95, 1.1, 1]}\n",
    "\n",
    "m.center_object(image)\n",
    "m.add_layer(image, vis_params, \"Landsat\")\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "68",
   "metadata": {},
   "source": [
    "Add a rectangle to the map."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "69",
   "metadata": {},
   "outputs": [],
   "source": [
    "region = ee.Geometry.BBox(-122.5955, 37.5339, -122.0982, 37.8252)\n",
    "fc = ee.FeatureCollection(region)\n",
    "style = {\"color\": \"ffff00ff\", \"fillColor\": \"00000000\"}\n",
    "m.add_layer(fc.style(**style), {}, \"ROI\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "70",
   "metadata": {},
   "source": [
    "To local drive"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "71",
   "metadata": {},
   "outputs": [],
   "source": [
    "geemap.ee_export_image(image, filename=\"landsat.tif\", scale=30, region=region)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "72",
   "metadata": {},
   "source": [
    "Check image projection."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "73",
   "metadata": {},
   "outputs": [],
   "source": [
    "projection = image.select(0).projection().getInfo()\n",
    "projection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "74",
   "metadata": {},
   "outputs": [],
   "source": [
    "crs = projection[\"crs\"]\n",
    "crs_transform = projection[\"transform\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "75",
   "metadata": {},
   "source": [
    "Specify region, crs, and crs_transform."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "76",
   "metadata": {},
   "outputs": [],
   "source": [
    "geemap.ee_export_image(\n",
    "    image,\n",
    "    filename=\"landsat_crs.tif\",\n",
    "    crs=crs,\n",
    "    crs_transform=crs_transform,\n",
    "    region=region,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "77",
   "metadata": {},
   "source": [
    "To Google Drive"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "78",
   "metadata": {},
   "outputs": [],
   "source": [
    "geemap.ee_export_image_to_drive(\n",
    "    image, description=\"landsat\", folder=\"export\", region=region, scale=30\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "79",
   "metadata": {},
   "outputs": [],
   "source": [
    "geemap.download_ee_image(image, \"landsat.tif\", scale=90)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "80",
   "metadata": {},
   "source": [
    "### Exporting Image Collections\n",
    "\n",
    "Image collections, like time series data, can be filtered and exported as multiple images. Here, a National Agriculture Imagery Program (NAIP) collection is filtered by date and location. The collection can then be saved locally or sent to Google Drive, making it easier to handle large datasets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "81",
   "metadata": {},
   "outputs": [],
   "source": [
    "point = ee.Geometry.Point(-99.2222, 46.7816)\n",
    "collection = (\n",
    "    ee.ImageCollection(\"USDA/NAIP/DOQQ\")\n",
    "    .filterBounds(point)\n",
    "    .filterDate(\"2008-01-01\", \"2018-01-01\")\n",
    "    .filter(ee.Filter.listContains(\"system:band_names\", \"N\"))\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "82",
   "metadata": {},
   "outputs": [],
   "source": [
    "collection.aggregate_array(\"system:index\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "83",
   "metadata": {},
   "source": [
    "To local drive"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "84",
   "metadata": {},
   "outputs": [],
   "source": [
    "geemap.ee_export_image_collection(collection, out_dir=\".\", scale=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85",
   "metadata": {},
   "source": [
    "To Google Drive"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "86",
   "metadata": {},
   "outputs": [],
   "source": [
    "geemap.ee_export_image_collection_to_drive(collection, folder=\"export\", scale=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "87",
   "metadata": {},
   "source": [
    "### Exporting Feature Collections\n",
    "\n",
    "Feature collections, such as state boundaries, are exportable in multiple formats (e.g., Shapefile, GeoJSON, and CSV). This example exports the Alaska state boundary as different vector formats both locally and to Google Drive. Additionally, exported data can be directly loaded into a GeoDataFrame for further manipulation in Python."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "88",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map()\n",
    "states = ee.FeatureCollection(\"TIGER/2018/States\")\n",
    "fc = states.filter(ee.Filter.eq(\"NAME\", \"Alaska\"))\n",
    "m.add_layer(fc, {}, \"Alaska\")\n",
    "m.center_object(fc, 4)\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "89",
   "metadata": {},
   "source": [
    "To local drive"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "90",
   "metadata": {},
   "outputs": [],
   "source": [
    "geemap.ee_to_shp(fc, filename=\"Alaska.shp\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "91",
   "metadata": {},
   "outputs": [],
   "source": [
    "geemap.ee_export_vector(fc, filename=\"Alaska.shp\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "92",
   "metadata": {},
   "outputs": [],
   "source": [
    "geemap.ee_to_geojson(fc, filename=\"Alaska.geojson\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "93",
   "metadata": {},
   "outputs": [],
   "source": [
    "geemap.ee_to_csv(fc, filename=\"Alaska.csv\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "94",
   "metadata": {},
   "outputs": [],
   "source": [
    "gdf = geemap.ee_to_gdf(fc)\n",
    "gdf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "95",
   "metadata": {},
   "outputs": [],
   "source": [
    "df = geemap.ee_to_df(fc)\n",
    "df"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "96",
   "metadata": {},
   "source": [
    "To Google Drive"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "97",
   "metadata": {},
   "outputs": [],
   "source": [
    "geemap.ee_export_vector_to_drive(\n",
    "    fc, description=\"Alaska\", fileFormat=\"SHP\", folder=\"export\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "98",
   "metadata": {},
   "source": [
    "## Creating Timelapse Animations\n",
    "\n",
    "### Landsat Timelapse\n",
    "\n",
    "The Landsat timelapse tool creates animations of changes over time. Here, we use a defined region of interest (ROI) to generate timelapse GIFs for Las Vegas (1984-2023):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "99",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map()\n",
    "roi = ee.Geometry.BBox(-115.5541, 35.8044, -113.9035, 36.5581)\n",
    "m.add_layer(roi)\n",
    "m.center_object(roi)\n",
    "m"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "100",
   "metadata": {},
   "outputs": [],
   "source": [
    "timelapse = geemap.landsat_timelapse(\n",
    "    roi,\n",
    "    out_gif=\"las_vegas.gif\",\n",
    "    start_year=1984,\n",
    "    end_year=2023,\n",
    "    bands=[\"NIR\", \"Red\", \"Green\"],\n",
    "    frames_per_second=5,\n",
    "    title=\"Las Vegas, NV\",\n",
    "    font_color=\"blue\",\n",
    ")\n",
    "geemap.show_image(timelapse)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "101",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map()\n",
    "roi = ee.Geometry.BBox(113.8252, 22.1988, 114.0851, 22.3497)\n",
    "m.add_layer(roi)\n",
    "m.center_object(roi)\n",
    "m"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "102",
   "metadata": {},
   "outputs": [],
   "source": [
    "timelapse = geemap.landsat_timelapse(\n",
    "    roi,\n",
    "    out_gif=\"hong_kong.gif\",\n",
    "    start_year=1990,\n",
    "    end_year=2022,\n",
    "    start_date=\"01-01\",\n",
    "    end_date=\"12-31\",\n",
    "    bands=[\"SWIR1\", \"NIR\", \"Red\"],\n",
    "    frames_per_second=3,\n",
    "    title=\"Hong Kong\",\n",
    ")\n",
    "geemap.show_image(timelapse)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "103",
   "metadata": {},
   "source": [
    "### Sentinel-2 Timelapse\n",
    "\n",
    "This example generates a timelapse of Sentinel-2 data for a selected ROI, with options to draw a custom ROI on the map. The timelapse spans 2017-2023, focusing on the June to September period each year."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "104",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map()\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "105",
   "metadata": {},
   "source": [
    "Pan and zoom the map to an area of interest. Use the drawing tools to draw a rectangle on the map. If no rectangle is drawn, the default rectangle shown below will be used."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "106",
   "metadata": {},
   "outputs": [],
   "source": [
    "roi = m.user_roi\n",
    "if roi is None:\n",
    "    roi = ee.Geometry.BBox(-74.7222, -8.5867, -74.1596, -8.2824)\n",
    "    m.add_layer(roi)\n",
    "    m.center_object(roi)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "107",
   "metadata": {},
   "outputs": [],
   "source": [
    "timelapse = geemap.sentinel2_timelapse(\n",
    "    roi,\n",
    "    out_gif=\"sentinel2.gif\",\n",
    "    start_year=2017,\n",
    "    end_year=2023,\n",
    "    start_date=\"01-01\",\n",
    "    end_date=\"12-31\",\n",
    "    frequency=\"year\",\n",
    "    bands=[\"SWIR1\", \"NIR\", \"Red\"],\n",
    "    frames_per_second=3,\n",
    "    title=\"Sentinel-2 Timelapse\",\n",
    ")\n",
    "geemap.show_image(timelapse)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "108",
   "metadata": {},
   "source": [
    "### MODIS Timelapse\n",
    "\n",
    "The MODIS timelapse can showcase NDVI (vegetation index) or ocean color data over time. In the vegetation example, we visualize NDVI from 2000-2022 with country overlays. The temperature example animates Aqua satellite data for monthly temperature trends from 2018-2020 with continent overlays."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "109",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map()\n",
    "m"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "110",
   "metadata": {},
   "outputs": [],
   "source": [
    "roi = m.user_roi\n",
    "if roi is None:\n",
    "    roi = ee.Geometry.BBox(-18.6983, -36.1630, 52.2293, 38.1446)\n",
    "    m.add_layer(roi)\n",
    "    m.center_object(roi)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "111",
   "metadata": {},
   "outputs": [],
   "source": [
    "timelapse = geemap.modis_ndvi_timelapse(\n",
    "    roi,\n",
    "    out_gif=\"ndvi.gif\",\n",
    "    data=\"Terra\",\n",
    "    band=\"NDVI\",\n",
    "    start_date=\"2000-01-01\",\n",
    "    end_date=\"2022-12-31\",\n",
    "    frames_per_second=3,\n",
    "    title=\"MODIS NDVI Timelapse\",\n",
    "    overlay_data=\"countries\",\n",
    ")\n",
    "geemap.show_image(timelapse)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "112",
   "metadata": {},
   "source": [
    "MODIS temperature"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "113",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = geemap.Map()\n",
    "m"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "114",
   "metadata": {},
   "outputs": [],
   "source": [
    "roi = m.user_roi\n",
    "if roi is None:\n",
    "    roi = ee.Geometry.BBox(-171.21, -57.13, 177.53, 79.99)\n",
    "    m.add_layer(roi)\n",
    "    m.center_object(roi)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "115",
   "metadata": {},
   "outputs": [],
   "source": [
    "timelapse = geemap.modis_ocean_color_timelapse(\n",
    "    satellite=\"Aqua\",\n",
    "    start_date=\"2018-01-01\",\n",
    "    end_date=\"2020-12-31\",\n",
    "    roi=roi,\n",
    "    frequency=\"month\",\n",
    "    out_gif=\"temperature.gif\",\n",
    "    overlay_data=\"continents\",\n",
    "    overlay_color=\"yellow\",\n",
    "    overlay_opacity=0.5,\n",
    ")\n",
    "geemap.show_image(timelapse)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "116",
   "metadata": {},
   "source": [
    "### GOES Timelapse\n",
    "\n",
    "GOES timelapse generation can animate atmospheric phenomena in near real-time. We create animations for different ROIs, including hurricane tracking and fire events using GOES-17 data with custom time windows and frame rates."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "117",
   "metadata": {},
   "outputs": [],
   "source": [
    "roi = ee.Geometry.BBox(167.1898, -28.5757, 202.6258, -12.4411)\n",
    "start_date = \"2022-01-15T03:00:00\"\n",
    "end_date = \"2022-01-15T07:00:00\"\n",
    "data = \"GOES-17\"\n",
    "scan = \"full_disk\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "118",
   "metadata": {},
   "outputs": [],
   "source": [
    "timelapse = geemap.goes_timelapse(\n",
    "    roi, \"goes.gif\", start_date, end_date, data, scan, framesPerSecond=5\n",
    ")\n",
    "geemap.show_image(timelapse)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "119",
   "metadata": {},
   "outputs": [],
   "source": [
    "roi = ee.Geometry.BBox(-159.5954, 24.5178, -114.2438, 60.4088)\n",
    "start_date = \"2021-10-24T14:00:00\"\n",
    "end_date = \"2021-10-25T01:00:00\"\n",
    "data = \"GOES-17\"\n",
    "scan = \"full_disk\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "120",
   "metadata": {},
   "outputs": [],
   "source": [
    "timelapse = geemap.goes_timelapse(\n",
    "    roi, \"hurricane.gif\", start_date, end_date, data, scan, framesPerSecond=5\n",
    ")\n",
    "geemap.show_image(timelapse)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "121",
   "metadata": {},
   "outputs": [],
   "source": [
    "roi = ee.Geometry.BBox(-121.0034, 36.8488, -117.9052, 39.0490)\n",
    "start_date = \"2020-09-05T15:00:00\"\n",
    "end_date = \"2020-09-06T02:00:00\"\n",
    "data = \"GOES-17\"\n",
    "scan = \"full_disk\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "122",
   "metadata": {},
   "outputs": [],
   "source": [
    "timelapse = geemap.goes_fire_timelapse(\n",
    "    roi, \"fire.gif\", start_date, end_date, data, scan, framesPerSecond=5\n",
    ")\n",
    "geemap.show_image(timelapse)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "123",
   "metadata": {},
   "source": [
    "## Data Visualization in 3D"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "124",
   "metadata": {},
   "outputs": [],
   "source": [
    "import leafmap.maplibregl as leafmap"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "125",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = leafmap.Map(style=\"3d-terrain\", projection=\"globe\")\n",
    "dataset = ee.ImageCollection(\"ESA/WorldCover/v200\").first()\n",
    "vis_params = {\"bands\": [\"Map\"]}\n",
    "m.add_ee_layer(dataset, vis_params, name=\"ESA Worldcover\", opacity=0.5)\n",
    "m.add_legend(builtin_legend=\"ESA_WorldCover\", title=\"ESA Landcover\")\n",
    "m"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "126",
   "metadata": {},
   "outputs": [],
   "source": [
    "m = leafmap.Map(style=\"darkmatter\", projection=\"globe\")\n",
    "dataset = ee.ImageCollection(\"NOAA/VIIRS/DNB/ANNUAL_V22\").filter(\n",
    "    ee.Filter.date(\"2022-01-01\", \"2023-01-01\")\n",
    ")\n",
    "nighttime = dataset.select(\"maximum\")\n",
    "nighttimeVis = {\"min\": 0.0, \"max\": 60.0}\n",
    "m.add_ee_layer(nighttime, nighttimeVis, name=\"Nighttime\")\n",
    "\n",
    "countries = ee.FeatureCollection(\"USDOS/LSIB_SIMPLE/2017\")\n",
    "styleParams = {\n",
    "    \"fillColor\": \"00000000\",\n",
    "    \"color\": \"ff0000\",\n",
    "    \"width\": 1.0,\n",
    "}\n",
    "countries = countries.style(**styleParams)\n",
    "m.add_ee_layer(countries, {}, name=\"Country Boundaries\")\n",
    "m"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "geo",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
